﻿using FB.Membership.Principal;
 
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Configuration;
using System.Web.Script.Serialization;
using System.Web.Security;

namespace FB.Membership
{
    public class FormsAuthenticationWrapper 
    {
        public static string CookieDomain { get { return FormsAuthentication.CookieDomain; } }

        public static HttpCookieMode CookieMode { get { return FormsAuthentication.CookieMode; } }

        public static bool CookiesSupported { get { return FormsAuthentication.CookiesSupported; } }

        public static string DefaultUrl { get { return FormsAuthentication.DefaultUrl; } }

        public static bool EnableCrossAppRedirects { get { return FormsAuthentication.EnableCrossAppRedirects; } }

        public static string FormsCookieName { get { return FormsAuthentication.FormsCookieName; } }

        public static string FormsCookiePath { get { return FormsAuthentication.FormsCookiePath; } }

        public static bool IsEnabled { get { return FormsAuthentication.IsEnabled; } }

        public static string LoginUrl { get { return FormsAuthentication.LoginUrl; } }

        public static bool RequireSSL { get { return FormsAuthentication.RequireSSL; } }

        public static bool SlidingExpiration { get { return FormsAuthentication.SlidingExpiration; } }

        public static TicketCompatibilityMode TicketCompatibilityMode { get { return FormsAuthentication.TicketCompatibilityMode; } }

        public static TimeSpan Timeout { get { return FormsAuthentication.Timeout; } }

        public static bool Authenticate(string name, string password)
        {
            return FormsAuthentication.Authenticate(name, password);
        }

        public static FormsAuthenticationTicket Decrypt(string encryptedTicket)
        {
            return FormsAuthentication.Decrypt(encryptedTicket);
        }

        public static void EnableFormsAuthentication(NameValueCollection configurationData)
        {
            FormsAuthentication.EnableFormsAuthentication(configurationData);
        }

        //[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        public static string Encrypt(FormsAuthenticationTicket ticket)
        {
            return FormsAuthentication.Encrypt(ticket);
        }

        public static HttpCookie GetAuthCookie(string userName, bool createPersistentCookie)
        {
            return FormsAuthentication.GetAuthCookie(userName, createPersistentCookie);
        }
        
        //[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        public static HttpCookie GetAuthCookie(string userName, bool createPersistentCookie, string strCookiePath)
        {
            return FormsAuthentication.GetAuthCookie(userName, createPersistentCookie, strCookiePath);
        }
        
        public static string GetRedirectUrl(string userName, bool createPersistentCookie)
        {
            return FormsAuthentication.GetRedirectUrl(userName, createPersistentCookie);
        }

        public static string HashPasswordForStoringInConfigFile(string password, string passwordFormat)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(password, passwordFormat);
        }

        public static void Initialize()
        {
            FormsAuthentication.Initialize();
        }

        public static void RedirectFromLoginPage(string userName, bool createPersistentCookie)
        {
            FormsAuthentication.RedirectFromLoginPage(userName, createPersistentCookie);
        }

        public static void RedirectFromLoginPage(string userName, bool createPersistentCookie, string strCookiePath)
        {
            FormsAuthentication.RedirectFromLoginPage(userName, createPersistentCookie, strCookiePath);
        }
        
        //[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        public static void RedirectToLoginPage()
        {
            FormsAuthentication.RedirectToLoginPage();
        }
        
        public static void RedirectToLoginPage(string extraQueryString)
        {
            FormsAuthentication.RedirectToLoginPage(extraQueryString);
        }
        
        public static FormsAuthenticationTicket RenewTicketIfOld(FormsAuthenticationTicket tOld)
        {
            return FormsAuthentication.RenewTicketIfOld(tOld);
        }
        
        public static void SetAuthCookie(string userName, bool createPersistentCookie)
        {
            FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
        }

        public static void SetAuthCookie(string userName, bool createPersistentCookie, string strCookiePath)
        {
            FormsAuthentication.SetAuthCookie(userName, createPersistentCookie, strCookiePath);
        }

        public static void SetAuthCookie(string userName, bool createPersistentCookie, IIdentityCookieModel cookieModel)
        {
            // SerializerJson
            var serializer = new JavaScriptSerializer();
            string userData = serializer.Serialize(cookieModel);
            DateTime expiration = (createPersistentCookie) ? DateTime.MaxValue : DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes);

            FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                1, // version number
                cookieModel.Name,
                DateTime.Now,
                expiration, 
                createPersistentCookie, 
                userData
                );
            
            string encTicket = FormsAuthentication.Encrypt(authTicket);
            HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
            faCookie.Domain = FormsAuthentication.CookieDomain;

            if (authTicket.IsPersistent)
            {
                faCookie.Expires = authTicket.Expiration;
            }

            HttpContext.Current.Response.AppendCookie(faCookie);
        }

        
        public static void SetHttpPrincipal(string cookieName)
        {
            var formsCookie = HttpContext.Current.Request.Cookies[cookieName];

            if (formsCookie != null)
            {
                var serializer = new JavaScriptSerializer();

                System.Threading.Thread.CurrentPrincipal = 
                HttpContext.Current.User = new FBPrincipal(
                    new FBIdentity(
                        serializer.Deserialize<FBIdentityCookieModel>(
                            FormsAuthentication.Decrypt(formsCookie.Value).UserData
                        )
                    ));

                
            }
        }


        public static T GetHttpCookieModel<T>(string cookieName) where T : IIdentityCookieModel, new()
        {
            var result = default(T);
             var formsCookie = HttpContext.Current.Request.Cookies[cookieName];

             if (formsCookie != null)
             {
                 var serializer = new JavaScriptSerializer();

                 result = serializer.Deserialize<T>(
                            FormsAuthentication.Decrypt(formsCookie.Value).UserData
                        );
             }

             return result;
        }


        public static void SignOut()
        {
            FormsAuthentication.SignOut();
        }

    }
}
